<template>
  <div id="tag-manager-container">
    <el-card class="tag-box">
      <template #header v-if="hasPerm('tag_cd')">
        <div class="card-content">
          <el-text type="primary" size="large" style="width: 100%; text-align: center">创建标签</el-text>
          <el-input
            v-model="createTagName"
            class="w-50 m-2"
            placeholder="请输入新标签名称"
            :suffix-icon="CollectionTag"
            style="width: 300px"
          />
          <el-button type="primary" @click="createTagHandle">创建</el-button>
        </div>
      </template>
      <div class="card-content" v-if="hasPerm('tag_cd')">
        <el-text type="primary" size="large" style="width: 100%; text-align: center">删除标签</el-text>
        <el-select v-model="removeTags" clearable placeholder="请选择" style="width: 260px; margin: 10px">
          <el-option v-for="tag in allTags" :key="tag.id" :label="tag.content" :value="tag.id" />
        </el-select>
        <el-button type="primary" @click="openConfirmBox('确认删除吗？图片标签也会一并删除', removeTagHandle)">
          删除标签
        </el-button>
      </div>
      <template #footer v-if="hasPerm('tag_update')">
        <div class="card-content">
          <el-text type="primary" size="large" style="width: 100%; text-align: center">修改标签</el-text>
          <el-input v-model="inputUpdateTagName" placeholder="请输入新名称">
            <template #prepend>
              <el-select v-model="selectUpdateTag" placeholder="选择标签" style="width: 115px">
                <el-option v-for="tag in allTags" :key="tag.id" :label="tag.content" :value="tag.id" />
              </el-select>
            </template>
            <template #append>
              <el-button :icon="Edit" @click="updateTagHandle"/>
            </template>
          </el-input>
        </div>
      </template>
    </el-card>
    <el-card class="tag-box" v-if="hasPerm('tag_stick')">
      <div class="card-content">
        <el-text type="primary" size="large" style="width: 100%; text-align: center">为数据集增删标签</el-text>
        <el-cascader
          :key="allTags"
          v-model="categoryOperationTagList"
          :props="selectorProps"
          clearable
          collapse-tags
          placeholder="请选择操作"
        />
        <el-button type="primary" @click="openConfirmBox('确认操作',operateCategotyHandle)" style="margin-left: 10px">执行</el-button>
      </div>
    </el-card>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, ref } from "vue"
import { CollectionTag, Edit } from "@element-plus/icons-vue"
import { ElMessage } from "element-plus"
import {
  createTagApi,
  getAllTagApi,
  deleteTagApi,
  getCategoryTagsApi,
  addTagToCategoryApi,
  deleteTagFromCategoryApi,
  updateTagApi
} from "@/api/data-manager/tagApi"
import { openConfirmBox } from "@/utils/confirmBox"
import { CascaderProps } from "element-plus/lib/components/index.js"
import { getParentCategoriesApi, getSubCategoriesApi } from "@/api/data-manager/categoryApi"
import emitter from "@/utils/mitt"
import { useLoginStore } from "@/store/loginStore"

const loginStore = useLoginStore()

function hasPerm(perm: string) : boolean {
    return loginStore.perms.includes(perm)
}

const allTags = ref<any[]>([])

const categoryOperationTagList = ref<any[] | null>()

function operateCategotyHandle() {
  if (categoryOperationTagList.value?.length === 0) {
    ElMessage.warning("进行选择后才能执行")
    return
  }
  setTimeout(async () => {
    let operation: any
    for (operation of categoryOperationTagList.value!) {
      try {
        await (operation[2] === "add"
          ? addTagToCategoryApi(operation[1], [operation[3]])
          : deleteTagFromCategoryApi(operation[1], [operation[3]]))
      } catch (error) {
        return
      }
    }
    emitter.emit("DM:category-tag-change")
    categoryOperationTagList.value = null
    ElMessage.success("操作成功")
  })
}

const selectorProps: CascaderProps = {
  multiple: true,
  lazy: true,
  lazyLoad(node, resolve) {
    const { level } = node
    setTimeout(async () => {
      if (level === 0) {
        let res
        try {
          res = await getParentCategoriesApi()
        } catch (error) {
          ElMessage.error("获取大类别列表失败")
          return
        }
        resolve(
          (res.data as any[]).map((data) => ({
            value: data.id,
            label: data.name,
            leaf: false
          }))
        )
      } else if (level === 1) {
        let res
        try {
          res = await getSubCategoriesApi(String(<number>node.value))
        } catch (error) {
          ElMessage.error("获取数据集列表失败")
          return
        }
        resolve(
          (res.data as any[]).map((data) => ({
            value: data.id,
            label: data.name,
            leaf: false
          }))
        )
      } else if (level === 2) {
        resolve([
          {
            value: "add",
            label: "添加",
            leaf: false
          },
          {
            value: "remove",
            label: "删除",
            leaf: false
          }
        ])
      } else {
        let res
        try {
          res = await getCategoryTagsApi(String(node.pathNodes[1].data?.value))
        } catch (error) {
          ElMessage.error("获取数据集标签失败")
          return
        }
        const categoryTags: any[] = res.data && res.data.length > 0 ? (res.data as any[]).map((tag) => tag.id) : []

        let addTags: any[] = []
        let removeTags: any[] = []

        allTags.value.forEach((tag) => {
          categoryTags.includes(tag.id) ? removeTags.push(tag) : addTags.push(tag)
        })

        resolve(
          (node.value === "add" ? addTags : removeTags).map((tag) => ({
            value: tag.id,
            label: tag.content,
            leaf: true
          }))
        )
      }
    })
  }
}

const selectUpdateTag = ref()
const inputUpdateTagName = ref<string>()

function updateTagHandle() {
    if (!(inputUpdateTagName.value && inputUpdateTagName.value !== "") || /^\s*$/.test(inputUpdateTagName.value)) {
        ElMessage.warning("请输入名称")
        return
    } else if (!selectUpdateTag.value) {
        ElMessage.warning("请输入待修改标签")
        return
    } else if (inputUpdateTagName.value?.trim() === getTagContent(selectUpdateTag.value)) {
        ElMessage.warning("请输入与原来不同的名称")
        return
    }
    setTimeout(async () => {
      let res
        try {
            res = await updateTagApi(selectUpdateTag.value,inputUpdateTagName.value?.trim()!)
        } catch (error) {
            ElMessage.error("更新标签失败")
            return
        }
        if (res.status === 40901) {
          ElMessage.error("已存在相同名称的标签")
          return
        }
        ElMessage.success("操作成功")
        selectUpdateTag.value = null
        inputUpdateTagName.value = ''
        emitter.emit("DM:tag-change")
        getTags()
        return
    })
}

function getTagContent(id : number) : string {
    let result : string = ''
    allTags.value.forEach(tag => {
        if (tag.id === id) {
            result = tag.content
            return
        }
    })
    return result
}


const removeTags = ref()

function removeTagHandle() {
  setTimeout(async () => {
    try {
      await deleteTagApi(removeTags.value)
    } catch (error) {
      ElMessage.error("处理操作失败")
      return
    }
    ElMessage.success("操作成功")
    removeTags.value = []
    getTags()
    emitter.emit("DM:tag-change")
  })
}

const createTagName = ref<string>()

function createTagHandle() {
  if (!(createTagName.value && createTagName.value !== "") || /^\s*$/.test(createTagName.value)) {
    ElMessage.warning("标签名不能为空")
    return
  }
  setTimeout(async () => {
    let res
    try {
      res = await createTagApi(createTagName.value!.trim())
    } catch (error) {
      ElMessage.error("处理失败，请稍后再试")
      return
    }
    if (res.status === 40902) {
      ElMessage.error("此标签名已经存在")
      return
    } else {
      ElMessage.success("操作成功")
      createTagName.value = ""
      getTags()
    }
    emitter.emit("DM:tag-change")
  })
}

function getTags() {
  allTags.value = []
  setTimeout(async () => {
    let res
    try {
      res = await getAllTagApi()
    } catch (error) {
      ElMessage.error("获取标签列表失败")
      return
    }
    allTags.value = res.data
  })
}

onMounted(() => {
  getTags()
})
</script>

<style lang="scss" scoped>
#tag-manager-container {
  height: 100%;
  width: 100%;
  display: flex;
  justify-content: space-around;
  align-items: center;
  .card-content {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
  }
  .tag-box {
    width: 500px;
  }
}
</style>
